package cn.js.sangu.unitStore.service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import cn.js.sangu.unitStore.entity.Setting;
import cn.js.sangu.unitStore.mapper.SettingMapper;

/**
 * 设置服务层
 * 继承ServiceImpl获得MyBatis Plus的完整CRUD能力
 */
@Service
public class SettingService extends ServiceImpl<SettingMapper, Setting> {

    // 通过BaseMapper调用自定义方法
    private final SettingMapper settingMapper;

    public SettingService(SettingMapper settingMapper) {
        this.settingMapper = settingMapper;
    }

    /**
     * 根据模块获取所有设置
     */
    public List<Setting> getSettingsByModule(String module) {
        // 使用LambdaQueryWrapper构建查询条件
        return baseMapper.selectList(Wrappers.<Setting>lambdaQuery()
                .eq(Setting::getModule, module));
    }

    /**
     * 根据键名获取设置
     */
    public Setting getSettingByKey(String key) {
        return baseMapper.selectOne(Wrappers.<Setting>lambdaQuery()
                .eq(Setting::getK, key));
    }

    /**
     * 获取所有设置
     * 使用MyBatis Plus提供的方法
     */
    public List<Setting> getAllSettings() {
        return baseMapper.selectList(null);
    }

    /**
     * 获取设置值
     */
    public String getSettingValue(String key) {
        Setting setting = getSettingByKey(key);
        return setting != null ? setting.getV() : null;
    }

    /**
     * 获取设置值（转换为布尔值）
     */
    public boolean getSettingBooleanValue(String key, boolean defaultValue) {
        String value = getSettingValue(key);
        return value != null ? Boolean.parseBoolean(value) : defaultValue;
    }

    /**
     * 保存设置（新增或更新）
     * 使用MyBatis Plus的条件更新方法
     */
    @Transactional
    public boolean saveSetting(Setting setting) {
        // 先查询是否存在
        Setting existing = baseMapper.selectOne(Wrappers.<Setting>lambdaQuery()
                .eq(Setting::getK, setting.getK()));

        if (existing != null) {
            // 存在则更新
            setting.setId(existing.getId());
            return baseMapper.updateById(setting) > 0;
        } else {
            // 不存在则新增
            return baseMapper.insert(setting) > 0;
        }
    }

    /**
     * 批量保存设置
     * 分别处理新增和更新操作
     */
    @Transactional
    public boolean batchSaveSettings(List<Setting> settings) {
        if (settings == null || settings.isEmpty()) {
            return true;
        }

        for (Setting setting : settings) {
            if (setting.getK() != null) {
                // 查询是否存在相同key的记录
                Setting existing = baseMapper.selectOne(Wrappers.<Setting>lambdaQuery()
                        .eq(Setting::getK, setting.getK()));

                if (existing != null) {
                    // 存在则更新
                    setting.setId(existing.getId());
                    baseMapper.updateById(setting);
                } else {
                    // 不存在则新增
                    baseMapper.insert(setting);
                }
            }
        }

        return true;
    }

    /**
     * 删除设置
     */
    @Transactional
    public boolean deleteSetting(String key) {
        return remove(Wrappers.<Setting>lambdaQuery()
                .eq(Setting::getK, key));
    }

    // 初始化方法已移至Controller层，使用更简洁的方式实现

    /**
     * 获取模块设置的Map格式
     */
    public Map<String, Object> getModuleSettingsMap(String module) {
        // 使用LambdaQueryWrapper查询指定模块的设置
        List<Setting> settings = baseMapper.selectList(Wrappers.<Setting>lambdaQuery()
                .eq(Setting::getModule, module));

        Map<String, Object> resultMap = new HashMap<>();

        for (Setting setting : settings) {
            // 检查键名是否为null，避免JSON序列化错误
            String key = setting.getK();
            if (key == null) {
                continue; // 跳过键名为null的设置项
            }

            String type = setting.getType();
            String value = setting.getV();

            if ("boolean".equals(type)) {
                resultMap.put(key, Boolean.parseBoolean(value));
            } else if ("number".equals(type)) {
                try {
                    resultMap.put(key, Integer.parseInt(value));
                } catch (NumberFormatException e) {
                    try {
                        resultMap.put(key, Double.parseDouble(value));
                    } catch (NumberFormatException ex) {
                        resultMap.put(key, value);
                    }
                }
            } else {
                resultMap.put(key, value);
            }
        }

        return resultMap;
    }
}
